package com.itdaan.portal.business.solr;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.BinaryRequestWriter;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SpellCheckResponse;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.client.solrj.response.SpellCheckResponse.Suggestion;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.util.DateUtil;

import com.itdaan.portal.common.util.ApplicationProperty;
/**
 * @author www.itdaan.com
 */
public class SolrClient {

	//记录日志
	private static Logger logger = Logger.getLogger(SolrClient.class);
	//内容
	private static HttpSolrServer server;
	//搜索建议
	private static HttpSolrServer logServer;
	
	//启动服务
	public static void startServer() throws Exception{
		if(server != null){
			return;
		}
		ApplicationProperty.init();
		server = new HttpSolrServer(ApplicationProperty.getProperty("solr.server.post"));
		server.setConnectionTimeout(1000);
		server.setDefaultMaxConnectionsPerHost(100);
		server.setMaxTotalConnections(100);
	}
	
	//添加文档
	public synchronized static boolean addDoc(Domain domain) throws SolrServerException, IOException{
			//创建输入文档
		SolrInputDocument doc = new SolrInputDocument();
		for(int i = 0;i < domain.oneNames.length;i++){
			doc.setField(domain.oneNames[i], ModelUtil.getValue(domain, domain.oneNames[i]));
		}
		server.add(doc);
		server.commit();
		return true;
	}	
	
	//批量添加文档
	public static void addDocs(List<Domain> docs) throws SolrServerException, IOException{
		for(Domain doc : docs){
			addDoc(doc);
		}
	}
	
	public static Map<String,Long> queryForGroups(){
		Map<String,Long> map = new HashMap<String,Long>();
		QueryResponse response = null;
		SolrQuery query = new SolrQuery("*:*");
		query.setFields("groupIds");
		// 开启facet查询
	    query.setFacet(true)
	    // 设置没有结果的栏目不显示
	            .setFacetMinCount(1)
	            // 设置根据栏目id进行facet查询
	            .addFacetField("groupIds");		
		try{
			response = server.query(query);
			List<Count> list = response.getFacetField("groupIds").getValues();
	        for (Count count : list) {
	        	map.put(count.getName(), count.getCount());
	        }			
		}catch (SolrServerException e){
			e.printStackTrace();
			return null;
		}
		return map;
	}	
	
	//查询总数量
	public static long queryForCount(String queryString){
		SolrQuery query = new SolrQuery(queryString);
		try{
			QueryResponse response = server.query(query);
			return response.getResults().getNumFound();
		}catch(Exception ex){
			ex.printStackTrace();
			return 0;
		}
	}
	
	//分页查询
	public static QueryResponse queryForPage(Domain domain,SolrPage page){
		QueryResponse response = null;
		SolrQuery query = new SolrQuery(domain.getQueryString());
		//设置返回的字段列表
		if(domain.names != null){
			query.setFields(domain.names);			
		}
		//设置每页显示条数
		query.setRows(page.getPageSize());
		//设置开始记录
		query.setStart((page.getCurPage()-1)*page.getPageSize());
		//排序字段
		if(!StringUtils.isEmpty(domain.getSortField())){
			String [] sortFields = domain.getSortField().split(",");
			for(String sortField : sortFields){
				query.addSort(sortField, ORDER.desc);
			}
		}
		//设置过滤
//		query.addFilterQuery(filter);
		
		//设置高亮
		query.setHighlight(true);  //开启高亮组件
		for(String hight : domain.hights){
			query.addHighlightField(hight);//高亮字段
		}
		query.setHighlightSimplePre("<B>");//标记，高亮关键字前缀
		query.setHighlightSimplePost("</B>");//后缀
		query.setHighlightSnippets(2);//结果分片数
		query.setHighlightFragsize(150);//每个分片的最大长度，默认为100
		
		//分组信息
		query.setFacet(true).setFacetMinCount(1).addFacetField("groupIds");
		
		try{
			response = server.query(query);
			SolrDocumentList list = response.getResults();
			//获取所有高亮的字段
			Map<String,Map<String,List<String>>> highlightMap = response.getHighlighting();
			for(SolrDocument solrDocument : list){
				String id = (String)solrDocument.get("id");
				for(String hight : domain.hights){
					List<String> hightlist = highlightMap.get(id).get(hight);
					if(hightlist != null && hightlist.size() > 0){
						solrDocument.setField(hight, hightlist.get(0).replace("<img", "").replace("&lt;img", ""));
					}else{//如果没有找到关键词高亮
						String value = (String)solrDocument.get(hight);
						if(value.length() > 150){
							value = value.substring(0,150);
						}
						value = value.replace("<img", "").replace("&lt;img", "");
						solrDocument.setField(hight, value);
					}
				}
			}
		} catch (SolrServerException e){
			e.printStackTrace();
			return null;
		}
		return response;
	}

	//根据标题查询相关内容
	public static QueryResponse queryForRelatives(Domain domain,SolrPage page){
		QueryResponse response = null;
		SolrQuery query = new SolrQuery(domain.getQueryString());
		//设置返回的字段列表
		if(domain.names != null){
			query.setFields(domain.names);			
		}
		//设置每页显示条数
		query.setRows(page.getPageSize());
		//设置开始记录
		query.setStart((page.getCurPage()-1)*page.getPageSize());
		//排序字段
		if(!StringUtils.isEmpty(domain.getSortField())){
			String [] sortFields = domain.getSortField().split(",");
			for(String sortField : sortFields){
				query.addSort(sortField, ORDER.desc);
			}
		}
		//设置过滤
//		query.addFilterQuery(filter);
		
		//设置高亮
		query.setHighlight(true);  //开启高亮组件
		for(String hight : domain.hights){
			query.addHighlightField(hight);//高亮字段
		}
		query.setHighlightSimplePre("<span>");//标记，高亮关键字前缀
		query.setHighlightSimplePost("</span>");//后缀
		query.setHighlightSnippets(2);//结果分片数
		query.setHighlightFragsize(150);//每个分片的最大长度，默认为100
		
		//分组信息
//		query.setFacet(true).setFacetMinCount(1).addFacetField("groupIds");
		
		try{
			response = server.query(query);
			SolrDocumentList list = response.getResults();
			//获取所有高亮的字段
			Map<String,Map<String,List<String>>> highlightMap = response.getHighlighting();
			for(SolrDocument solrDocument : list){
				String id = (String)solrDocument.get("id");
				for(String hight : domain.hights){
					List<String> hightlist = highlightMap.get(id).get(hight);
					if(hightlist != null && hightlist.size() > 0){
						solrDocument.setField(hight, hightlist.get(0).replace("<img", "").replace("&lt;img", ""));
					}else{//如果没有找到关键词高亮
						String value = (String)solrDocument.get(hight);
						if(value.length() > 150){
							value = value.substring(0,150);
						}
						value = value.replace("<img", "").replace("&lt;img", "");
						solrDocument.setField(hight, value);
					}
				}
			}
		} catch (SolrServerException e){
			e.printStackTrace();
			return null;
		}
		return response;
	}	

   /**
    * 查询单个文档
    * @param domain
    * @return
    */
   public static Domain queryOne(Domain domain){
		SolrQuery query = new SolrQuery();
		query.setQuery(domain.getQueryString());
		try {
			QueryResponse response = server.query(query);
			Long elapsedTime = response.getElapsedTime(); 
			SolrDocumentList docs = response.getResults();
			for(SolrDocument doc : docs){
				for(String name : domain.oneNames){
					ModelUtil.setValue(domain, name, doc.get(name));
				}
				domain.setElapsedTime(elapsedTime);
				break;
			}
		} catch (Exception e) {
			logger.error("从solr根据id查询单个文档时遇到错误", e);
		}	   
		return domain;
   }
	
	
	public static void clear() {
		server.setRequestWriter(new BinaryRequestWriter());
		try {
			server.deleteByQuery("*:*");
			server.commit();
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static List<String> getSuggestions(String kw) {
	    SolrQuery query = new SolrQuery();
	    query.setRequestHandler("/suggest");
	    query.setQuery("id:" + kw);

	    try {
	        SpellCheckResponse spellCheckResponse = logServer.query(query).getSpellCheckResponse();
	        // solr 数字拼写提示没有返回
	        if (spellCheckResponse == null) {
	            return null;
	        }
	        
	        List<Suggestion> suggestions = spellCheckResponse.getSuggestions();
	        if (suggestions.size() == 0) {
	            return null;
	        } else {
	            Suggestion suggestion = suggestions.get(suggestions.size()-1);
	            return suggestion.getAlternatives();
	        }
	    } catch (SolrServerException e) {
	        logger.error("获取推荐词时遇到错误:", e);
	        return null;
	    }
	}	
	
	/**
	 * 增量/全量建立索引 。
	 * 
	 * @param entity, 对哪个核进行操作
	 * @param delta ture，增量建立索引；false，重建所有索引
	 */
	public static void buildDeltaIndex(String entity) {
		SolrQuery query = new SolrQuery();
		// 指定RequestHandler，默认使用/select
		query.setRequestHandler("/dataimport");

		query.setParam("command", "delta-import")
			 .setParam("clean", false)
			 .setParam("commit", true)
			 .setParam("entity", entity)
			 .setParam("optimize", false);
		try {
			if ("post".equals(entity)) {
				server.query(query);
			}
			
			if ("searchlog".equals(entity)) {
				logServer.query(query);
			}
			
		} catch (SolrServerException e) {
			logger.error("建立索引时遇到错误，", e);
		}
	}	
	
	/**
	 * 查询相关的数据
	 * @param id
	 * @param count
	 * @return
	 */
	public static List<Post> getRelated(String id, int count) {
		SolrQuery query = new SolrQuery();
		// 指定RequestHandler，默认使用/select
		query.setRequestHandler("/mlt");
		
		List<Post> posts = new ArrayList<Post>();
		try {
			String q = "id:"+id;
			query.setQuery(q)
				.setParam("fl", "id,title,typeId,postTime,isHtmlCreated")
				.setParam("mlt", "true")
				.setParam("mlt.fl", "title")
				.setParam("mlt.mindf", "1")
				.setParam("mlt.mintf", "1");
//			if(isImg)	
//			query.addFilterQuery("firstImg:*img.itdaan.com*" );
			query.setRows(count);// mlt.count无效，需要此方法控制返回条数
			
			QueryResponse response =  server.query(query);
			if (response == null) return posts;

			SolrDocumentList docs = response.getResults();
			Iterator<SolrDocument> iter = docs.iterator();
			SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
			while (iter.hasNext()) {
				// 相关结果中不包含自己，循环中无需排除处理
				SolrDocument doc = iter.next();
				String idStr = doc.getFieldValue("id").toString();
				Post post = new Post();
				post.setId(Long.parseLong(idStr));
				post.setTitle(doc.getFieldValue("title").toString());
				post.setTypeId(doc.getFieldValue("typeId").toString());
				Date date = DateUtil.parseDate(doc.getFieldValue("postTime").toString());
				post.setPostTimeStr(format.format(date));
				post.setIsHtmlCreated(Integer.parseInt(doc.getFieldValue("isHtmlCreated").toString()));
				posts.add(post);
			}
		} catch (Exception e) {
			logger.error("从solr获取相关文章时遇到错误", e);
		}
		return posts;
	}	
	
	public static void main(String[] args) {
		try {
			startServer();
			System.out.println(queryForGroups());
		} catch (Exception e) {
			e.printStackTrace();
		}
		Post post = new Post();
		post.setQueryString("id:76");
		post = (Post)queryOne(post);
		System.out.println(post.getContent());
//		
//		clear();
	}
	
}
